package main

import "fmt"

type Sender interface {
	Send(string) error
}

type EmailSender struct {
	Adder string
	To    string
}

type DingDingSender struct{}

func (s EmailSender) Send(msg string) error {
	fmt.Println("email send: ", msg)
	return nil
}

func (s DingDingSender) Send(msg string) error {
	fmt.Println("dingding send: ", msg)
	return nil
}

func (s EmailSender) Test() {
	fmt.Println("test")
}

func test(sender Sender) {
	if _, ok := sender.(*DingDingSender); ok {
		fmt.Println("DingDing Sender")
	} else if _, ok := sender.(*EmailSender); ok {
		fmt.Println("Email Sender")
	} else {
		fmt.Println("Error")
	}
}

func query(sender Sender) {
	// 类型查询
	// switch case + 接口变量.(type)
	switch obj := sender.(type) {
	case *EmailSender:
		fmt.Println("email sender", obj.Adder)
	case *DingDingSender:
		fmt.Println("dingding sender")
	default:
		fmt.Println("error")
	}
}

func main() {
	var sender Sender = &EmailSender{"xxx", "yyy"}
	sender.Send("aa")

	// 断言
	obj, ok := sender.(*EmailSender)
	fmt.Printf("%T,%#v,%#v\n", obj, obj, ok)
	if ok {
		fmt.Println(obj.Adder)
		fmt.Println(obj.To)
		obj.Test()
	}

	test(sender)
	query(sender)
	query(new(DingDingSender))
}
